package cn.com.anypay.manager.service.impl;

import cn.com.anypay.manager.miaoma.config.Config;
import cn.com.anypay.manager.miaoma.config.ConfigService;
import cn.com.anypay.manager.service.OcrService;
import cn.com.anysdk.ocr.config.OcrProperties;
import cn.com.anysdk.ocr.config.OcrProperties.AliyunProperties;
import cn.com.anysdk.ocr.config.OcrProperties.OcrKeyConfig;
import cn.com.anysdk.ocr.exception.OcrException;
import cn.com.anysdk.ocr.factory.OcrServiceFactory;
import cn.com.anysdk.ocr.model.OcrOptions;
import cn.com.anysdk.ocr.model.OcrResult;
import cn.com.anysdk.ocr.service.IOcrService;

import cn.com.anypay.manager.common.utils.AnyJsonUtils;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.util.Map;

@Slf4j
@Service
public class OcrServiceImpl implements OcrService {

    private IOcrService currentOcrService;
    private OcrProperties currentOcrConfig;
    private static final String SERVICE_TYPE = "OCR";

    @Resource
    private ConfigService configService;

    @PostConstruct
    public void init() {
        try {
            // 使用默认配置初始化，不从数据库读取
            log.info("OCR服务使用默认配置初始化");
            OcrProperties defaultConfig = new OcrProperties();
            defaultConfig.setProvider("mock");
            currentOcrConfig = defaultConfig;
            currentOcrService = OcrServiceFactory.createService(currentOcrConfig);
            log.info("OCR服务初始化成功，类型: {}", currentOcrConfig.getProvider());
        } catch (Exception e) {
            log.error("OCR服务初始化失败: {}", e.getMessage(), e);
            // 初始化失败时使用默认配置
            OcrProperties defaultConfig = new OcrProperties();
            defaultConfig.setProvider("mock");
            currentOcrConfig = defaultConfig;
            currentOcrService = OcrServiceFactory.createService(currentOcrConfig);
        }
    }

    @Override
    public String switchProvider(Map<String, Object> config) {
        log.info("切换OCR服务商，参数: {}", config);
        OcrProperties ocrConfig = createConfigFromMap(config);
        currentOcrService = OcrServiceFactory.createService(ocrConfig);
        currentOcrConfig = ocrConfig;

        // 保存配置到数据库
        Config serviceConfig = configService.saveConfig(SERVICE_TYPE, ocrConfig.getProvider(), config);
        log.debug("保存OCR配置成功: {}", serviceConfig);

        log.info("OCR服务商切换为: {}", ocrConfig.getProvider());
        return "OCR Provider switched to: " + ocrConfig.getProvider();
    }

    /**
     * 获取当前OCR服务商配置
     *
     * @return 配置信息Map
     * @throws OcrException 未初始化时抛出
     */
    @Override
    public Map getCurrentConfig() throws OcrException {
        try {
            // 如果当前配置为空，尝试从数据库加载
            if (currentOcrConfig == null) {
                Config serviceConfig = configService.getConfig(SERVICE_TYPE, null);
                if (serviceConfig != null) {
                    Map<String, Object> configMap = AnyJsonUtils.toMap(serviceConfig.getConfigJson());
                    currentOcrConfig = createConfigFromMap(configMap);
                    currentOcrService = OcrServiceFactory.createService(currentOcrConfig);
                    return configMap;
                }
                throw new OcrException("OCR configuration not found");
            }

            // 如果当前配置是默认的mock配置，返回null表示没有配置
            if ("mock".equals(currentOcrConfig.getProvider())) {
                return null;
            }

            Config serviceConfig = configService.getConfig(SERVICE_TYPE, currentOcrConfig.getProvider());
            if (serviceConfig == null) {
                throw new OcrException("OCR configuration not found");
            }
            return AnyJsonUtils.parseMap(serviceConfig.getConfigJson());
        } catch (Exception e) {
            log.error("获取OCR配置失败: {}", e.getMessage(), e);
            throw new OcrException("Failed to get OCR configuration", e);
        }
    }

    @Override
    public Map<String, Object> getConfigByProvider(String provider) throws OcrException {
        try {
            log.info("根据提供商获取OCR配置: {}", provider);
            Config serviceConfig = configService.getConfig(SERVICE_TYPE, provider);
            if (serviceConfig == null) {
                log.info("数据库中未找到{}类型的OCR配置", provider);
                return null;
            }
            Map<String, Object> configMap = AnyJsonUtils.parseMap(serviceConfig.getConfigJson());
            log.info("成功获取{}类型的OCR配置", provider);
            return configMap;
        } catch (Exception e) {
            log.error("根据提供商获取OCR配置失败: {}", e.getMessage(), e);
            throw new OcrException("Failed to get OCR configuration by provider: " + provider, e);
        }
    }

    /**
     * 识别图片文件中的文字
     * @param file 图片文件
     * @return 识别结果
     */
    @Override
    public OcrResult recognize(MultipartFile file, String serviceType) throws OcrException {
        if (currentOcrService == null) {
            log.warn("识别请求失败，OCR服务未初始化");
            throw new OcrException("OCR服务未初始化，请先配置服务商");
        }

        try {
            File tempFile = File.createTempFile("ocr_", file.getOriginalFilename());
            file.transferTo(tempFile);

            log.info("识别图片文件: {}, OCR类型: {}", tempFile.getAbsolutePath(), serviceType);
            OcrOptions options = OcrOptions.defaultOptions();

            // 根据serviceType设置不同的OCR选项
            if (serviceType == null || serviceType.trim().isEmpty()) {
                log.info("未指定OCR类型，使用通用文字识别");
                options.setType("");
            } else {
                switch (serviceType) {
                    case "general" -> options.setType("general");
                    case "idCard" -> options.setType("id_card");
                    case "bankCard" -> options.setType("bank_card");
                    case "businessLicense" -> options.setType("invoice"); // 使用发票识别代替营业执照识别
                    default -> {
                        log.warn("未知的OCR类型: {}, 使用通用文字识别", serviceType);
                        options.setType("");
                    }
                }
            }

            log.debug("OCR选项: type={}", options.getType());
            OcrResult result = currentOcrService.recognize(tempFile, options);
            log.info("识别完成，结果: {}", result);

            // 清理临时文件
            tempFile.delete();

            return result;
        } catch (Exception e) {
            log.error("OCR识别失败", e);
            throw new OcrException("OCR识别失败: " + e.getMessage());
        }
    }

    /**
     * 根据配置Map创建OcrProperties
     * @param config 配置参数
     * @return OcrProperties
     */
    private OcrProperties createConfigFromMap(Map<String, Object> config) {
        String provider = (String) config.get("type");
        if (provider == null || provider.isEmpty()) {
            log.error("缺少OCR服务商类型参数");
            throw new OcrException("Missing provider type");
        }

        return switch (provider.toLowerCase()) {
            case "aliyun" -> {
                String accessKeyId = (String) config.get("accessKeyId");
                String accessKeySecret = (String) config.get("accessKeySecret");
                String endpoint = (String) config.get("endpoint");
                String regionId = (String) config.get("regionId");

                if (accessKeyId == null || accessKeyId.isEmpty() ||
                    accessKeySecret == null || accessKeySecret.isEmpty()
                ) {
                    log.error("阿里云OCR配置缺少必要参数: accessKeyId 或 accessKeySecret");
                    throw new OcrException("阿里云OCR配置缺少必要参数");
                }

                OcrProperties ocrProperties = new OcrProperties();
                ocrProperties.setProvider(provider);

                AliyunProperties aliyunProperties = new AliyunProperties();

                // 创建通用配置
                OcrKeyConfig generalConfig = new OcrKeyConfig();
                generalConfig.setAccessKeyId(accessKeyId);
                generalConfig.setAccessKeySecret(accessKeySecret);
                generalConfig.setEndpoint(endpoint);
                generalConfig.setRegion(regionId);
                aliyunProperties.setGeneral(generalConfig);

                // 创建身份证识别配置
                OcrKeyConfig idCardConfig = new OcrKeyConfig();
                idCardConfig.setAccessKeyId(accessKeyId);
                idCardConfig.setAccessKeySecret(accessKeySecret);
                idCardConfig.setEndpoint(endpoint);
                idCardConfig.setRegion(regionId);
                aliyunProperties.setIdCard(idCardConfig);

                // 创建银行卡识别配置
                OcrKeyConfig bankCardConfig = new OcrKeyConfig();
                bankCardConfig.setAccessKeyId(accessKeyId);
                bankCardConfig.setAccessKeySecret(accessKeySecret);
                bankCardConfig.setEndpoint(endpoint);
                bankCardConfig.setRegion(regionId);
                aliyunProperties.setBankCard(bankCardConfig);

                // 创建营业执照识别配置
                OcrKeyConfig businessLicenseConfig = new OcrKeyConfig();
                businessLicenseConfig.setAccessKeyId(accessKeyId);
                businessLicenseConfig.setAccessKeySecret(accessKeySecret);
                businessLicenseConfig.setEndpoint(endpoint);
                businessLicenseConfig.setRegion(regionId);
                aliyunProperties.setBusinessLicense(businessLicenseConfig);

                ocrProperties.setAliyun(aliyunProperties);

                log.debug("构建阿里云OCR配置: {}", aliyunProperties);
                yield ocrProperties;
            }
            case "mock" -> {
                log.info("使用Mock OCR配置");
                OcrProperties ocrProperties = new OcrProperties();
                ocrProperties.setProvider(provider);
                yield ocrProperties;
            }
            default -> {
                log.error("不支持的OCR服务商类型: {}", provider);
                throw new OcrException("不支持的OCR服务商类型: " + provider);
            }
        };
    }
}
